package viz.view.mediators
{
	import flare.vis.data.NodeSprite;
	
	import flash.events.Event;
	import flash.events.MouseEvent;
	
	import mx.controls.Button;
	import mx.core.Application;
	import mx.events.FlexEvent;
	import mx.events.ListEvent;
	import mx.events.ListEventReason;
	
	import org.puremvc.as3.multicore.interfaces.INotification;
	import org.puremvc.as3.multicore.patterns.mediator.Mediator;
	
	import viz.model.flare.data.ActionItem;
	import viz.model.flare.data.StateItem;
	import viz.view.forms.StateForm;

	public class StateFormMediator extends Mediator
	{
		
		public static const NAME:String ="StateFormMediator";
		
		public static const STATE_FORM_READY:String = "stateForm/ready";
		public static const STATE_FORM_REMOVE:String = "stateForm/remove";
		public static const STATE_FORM_CHANGE_DATA:String = "stateForm/changeData";
		public static const REMOVE_STATE_REQUEST:String = "stateForm/removeStateRequest";
		public static const COMMIT_CHANGES:String = "stateForm/commitChanges";
		public static const UPDATE_REQUEST:String = "stateForm/updateRequest";
		public static const SELECT_ACTION:String = "stateForm/selectAction";
		public static const ADD_ACTION:String = "stateForm/addAction";
		public static const REMOVE_ITEM:String = "stateForm/removeItem";
		
		
		
		private var application:Application;
		private var isCreated:Boolean;
		private var state:StateItem;
		private var panelMap:Array;

		public function StateFormMediator( state:StateItem )
		{
			super(NAME, new StateForm());
			initMediator( state );
		}
		
		private function initMediator( state:StateItem ):void{
			this.state = state;
			view.addEventListener(FlexEvent.CREATION_COMPLETE, onCreationComplete);
		}
		
		override public function listNotificationInterests():Array{
			return [ STATE_FORM_CHANGE_DATA,
					COMMIT_CHANGES,
					ADD_ACTION,
					REMOVE_ITEM ];
		}
		
		override public function handleNotification(note:INotification):void{
			switch(note.getName()){
				case STATE_FORM_CHANGE_DATA:
					changeData(note.getBody());
					break;
					
				case COMMIT_CHANGES: 
					commitChanges(); 
					break;
					
				case ADD_ACTION: 
					addAction(); 
					break;
					
				case REMOVE_ITEM: 
					removeItem(); 
					break;
			}
		}
		
		private function removeItem():void{
			var editor:Object = view.actions.editedItemRenderer,
				action:ActionItem;
			if(editor){
				action = ActionItem(editor.data);
				removeAction(action);
			}else{
				removeState()
			}
		}
		
		private function addAction():void{
			var action:ActionItem= new ActionItem(),
				row:int = view.actions.dataProvider.length;
			action.name = "not set";
			action.source = state;
			state.addAction( action );
			view.actions.editedItemPosition = {columnIndex:0, rowIndex:row};
		}
		
		private function removeAction(action:ActionItem):void{
			state.removeAction(action);
			sendUpdateRequestNote();
		}
		
		private function getState( data:Object ):StateItem{
			if(data is NodeSprite ){
				return StateItem( NodeSprite( data ).data );
			}else if( data is StateItem ){
				return StateItem( data );
			}else{
				return null;
			}
		}
		
		private function changeData( data:Object):void{
			state = getState( data );
			if(!state)return;
			if(isCreated)commitChanges();
			if(!view.visible)view.visible = true;
			resetView();
			
		}
		
		private function onCreationComplete(event:FlexEvent):void{
			view.removeEventListener(FlexEvent.CREATION_COMPLETE, onCreationComplete);
			view.addEventListener(Event.REMOVED, onRemoved);
			isCreated = true;
			activate();
		}
		
		private function onRemoved(event:Event):void{
			if(event.target != view )return;
			view.removeEventListener(Event.REMOVED, onRemoved);
			deactivate();
			setViewComponent( null );
			facade.removeMediator( mediatorName );
		}
		
		public function activate():void{
			resetView();
			addListeners();
		}
		
		private function resetView():void{
			view.data = state;
			view.input.setFocus();
		}
		
		public function deactivate():void{
			removeListeners();
		}
		
		 private  function addListeners():void{
			view.addEventListener(MouseEvent.CLICK, onClick);
			view.actions.addEventListener(ListEvent.CHANGE, onListChange);
			view.actions.addEventListener(ListEvent.ITEM_EDIT_END, onListEditEnd);
		}
		
		private function onListEditEnd(event:ListEvent):void{
			if(event.reason == ListEventReason.NEW_ROW)
				sendUpdateRequestNote();
		}
		
		 private function removeListeners():void{
			view.removeEventListener(MouseEvent.CLICK, onClick);
			view.actions.removeEventListener(ListEvent.CHANGE, onListChange)
			view.actions.removeEventListener(ListEvent.ITEM_EDIT_END, onListEditEnd);
		}
		
		public function onListChange(event:ListEvent):void{
			var action:ActionItem = ActionItem(event.itemRenderer.data);
			if(!action.name || !action.target ) return
			state.currentAction = action;
			sendSelectActionNote();
		}
		
		override public function onRegister():void{
			sendReadyNote();
		}
		
		
		

		private function onClick(event:MouseEvent):void{
			var target:Button = event.target as Button;
			if(!target)return;
			switch( target.name){
				case view.deleteState.name:
					removeState();
					break;
			} 
		}
		
		private function removeState():void{
			sendRemoveStateNote();
			view.data = null;
			view.visible = false;
			sendUpdateRequestNote();

		}
		private function sendRemoveStateNote():void{
			sendNotification(REMOVE_STATE_REQUEST, state)
		}
		private function sendRemoveViewNote():void{
			sendNotification(STATE_FORM_REMOVE, view)
		}
		private function sendSelectActionNote():void{
			sendNotification(SELECT_ACTION, state);
		}
		
		private function sendUpdateRequestNote():void{
			sendNotification(UPDATE_REQUEST);
		}
		
		private function sendReadyNote():void{
			sendNotification(STATE_FORM_READY, view);
		}
		
		private function commitChanges():void{
			view.pkg.commit();
			if( view.commit() )
				sendUpdateRequestNote();
		} 
		
		

	
		public function get view():StateForm{
			return StateForm( viewComponent );
		}
		
	}
}